import logging
import random
import re
from datetime import datetime

from flask import abort,make_response, jsonify
from flask import current_app
from flask import request
from flask import session

from info import constants, db
from info.libs.yuntongxun.sms import CCP
from info.models import User
from info.utils.response_code import RET
from . import passport_blue
from info.utils.captcha.captcha import captcha
from info import redis_store



@passport_blue.route("/logout", methods=['POST'])
def logout():
    """
    清除session中的对应登录之后保存的信息
    :return:
    """
    session.pop('user_id', None)
    session.pop('nick_name', None)
    session.pop('is_admin', None)


    # 返回结果
    return jsonify(errno=RET.OK, errmsg="OK")


@passport_blue.route('/login',methods=['POST'])
def login():
	# 一.获取参数
	mobile = request.json.get('mobile')
	password = request.json.get('password')
	#二.校验参数
	# 1.完整性
	if not all([mobile,password]):
		return jsonify(errno=RET.PARAMERR,errmsg='参数不全')
	#2.手机号
	if not re.match(r'^1[3456789][0-9]{9}$',mobile):
		return jsonify(errno=RET.PARAMERR,errmsg='手机号码填写错误')

	#三.逻辑处理
	#1.查询用户
	try:
		user = User.query.filter_by(mobile=mobile).first()
	except Exception as e:
		current_app.logger.error(e)
		return jsonify(erron=RET.DBERR,errmsg='查询数据库错误')


	#2.验证密码
	if not user or not user.check_password(password):
		return jsonify(errno=RET.DATAERR,errmsg='用户名或密码错误')

	#3.设置session
	session['user_id'] = user.id
	session['nick_name'] = user.nick_name

	#4.设置最后登录
	user.last_login = datetime.now()
	try:
		db.session.commit()
	except Exception as e:
		db.session.rollback()
		current_app.logger.error(e)
		return jsonify(erron=RET.DBERR,errmsg='数据库错误')


	#四.返回数据
	return jsonify(errno=RET.OK,errmsg='登录成功')






"""
#一.获取参数
#二.校验参数
1.完整性
2.手机号

#三.逻辑处理
1.对比验证码
    1.1 从redis中获取短信验证码
    1.2 对比验证码
    1.3 对比成功,删除验证码

2.注册用户
    2.1 判断是否注册
    2.2 创建模型
    2.3 注册用户

3.设置登录
    设置session数据实现登录

#四.返回数据
返回成功信息

"""
# URL: register
# 请求方式: POST
# 参数: password, sms_code, mobile

@passport_blue.route('/register',methods=['POST'])
def register():
	# 一.获取参数
	mobile = request.json.get('mobile')
	sms_code = request.json.get('sms_code')
	password = request.json.get('password')


	# 二.校验参数
	# 1.完整性
	if not all([mobile,sms_code,password]):
		return jsonify(errno=RET.PARAMERR,errmsg='参数不全')

	# 2.手机号
	if not re.match(r'^1[3456789][0-9]{9}$',mobile):
		return jsonify(errno=RET.PARAMERR,errmsg='手机填写错误')
	# 三.逻辑处理
	# 1.对比验证码
	# 1.1 从redis中获取短信验证码
	try:
		real_sms_code = redis_store.get('sms_code_' + mobile)
	except Exception as e:
		current_app.logger.error(e)
		return jsonify(erron=RET.DBERR,errmsg='获取短信验证码错误')

	if not real_sms_code:
		return jsonify(errno=RET.NODATA,errmsg='验证码已过期或手机号填写错误')
	# 1.2 对比验证码

	if real_sms_code != sms_code:
		return jsonify(errno=RET.DATAERR,errmsg='验证码填写错误')
	# 1.3 对比成功, 删除验证码

	try:
		redis_store.delete('sms_code_' + mobile)
	except Exception as e:
		current_app.logger.error(e)
		return jsonify(erron=RET.DBERR,errmsg='删除redis错误')
	# 2.注册用户
	# 2.1 判断是否注册

	try:
		user_model = User.query.filter_by(mobile=mobile).first()
	except Exception as e:
		current_app.logger.error(e)
		return jsonify(erron=RET.DBERR,errmsg='数据库错误')

	if user_model:
		return jsonify(errno=RET.DATAEXIST,errmsg='手机号以注册')

	# 2.2 创建模型
	user_model = User()
	user_model.nick_name = mobile
	user_model.mobile = mobile
	user_model.password = password
	# 2.3 注册用户
	try:
		db.session.add(user_model)
		db.session.commit()
	except Exception as e:
		db.session.rollback()
		current_app.logger.error(e)
		return jsonify(erron=RET.DBERR,errmsg='数据库错误')

	# 3.设置登录
	# 设置session数据实现登录
	# 设置session: 1.将界面上的常用信息存储起来,要显示的时候,直接从session读取
	# 2.存储用户的id值,将来在调用接口时,用来验证用户是否存在
	try:
		session['nick_name'] = mobile
		session['user_id'] = user_model.id
	except Exception as e:
		current_app.logger.error(e)
		return jsonify(erron=RET.DBERR,errmsg='session保存redis数据库失败')
	# 四.返回数据
	return jsonify(errno=RET.OK,errmsg='请求成功')







# URL:sms_code
# 请求方式： POST (一般获取数据用GET,提交数据用POST)
# 参数：image_code_id,image_code,mobile
# 返回数据：JSON格式的数据
@passport_blue.route('/sms_code',methods=['POST'])
def sms_code():
	"""
	获取参数
	从redis获取数据
	对比图像验证码的值
	对比成功，自己生成验证码
	保存验证码到redis
	发送短信

	"""
	# 一.获取参数
	json_data = request.json
	image_code = json_data.get('image_code')
	image_code_id = json_data.get('image_code_id')
	mobile = json_data.get('mobile')

	# 二.校验参数
	# 2.1 验证完整性
	if not all([image_code_id,image_code,mobile]):
		# 如果数据有任何一个没有值,就会进入这里
		# 以后需要返回错误信息和错误码
		# error_dict = {
		# 	'errno':'4001',
		# 	'errmsg':'参数不全'
		# }
		return jsonify(errno=RET.PARAMERR,errmsg='参数不全')
	# 2.2 验证手机号是否正确
	if not re.match(r'1[3456789][0-9]{9}',mobile):
		return jsonify(errno=RET.PARAMERR,errmsg='手机号码有误')
	# 三.逻辑处理
	#1.对比图像验证码



	# 1.1从redis获取数据
	try:
		real_image_code = redis_store.get('image_code_id_' + image_code_id)
	except Exception as e:
		current_app.logger.error(e)
		return jsonify(errno=RET.DBERR,errmsg='redis读取验证码失败')
	# 以后读取redis/myisql一定要判断数据是否为空
	if not real_image_code:
		return jsonify(errno=RET.NODATA,errmsg='验证码已过期')

	#1.2 删除图像验证码
	try:
		redis_store.delete('image_code_id_' + image_code_id)
	except Exception as e:
		current_app.logger.error(e)
		return jsonify(erron=RET.DBERR,errmsg='删除redis数据库失败')

	# 1.3. 对比图像验证码的值
	# abc1 = ABC1
	if real_image_code.lower() != image_code.lower():
		return jsonify(errno=RET.DATAERR,errmsg='验证码填写错误')


	# 2.发送短信
	# 2.1 判断是否注册

	try:
		user = User.query.filter_by(mobile=mobile).first()
	except Exception as e:
		current_app.logger.error(e)
		return jsonify(erron=RET.DBERR,errmsg='数据库错误')

	if user:
		return jsonify(errno=RET.DATAEXIST,errmsg='手机号已注册')

	# 2.2 对比成功,自己生成验证码
	# %06d:6位，不足以0补齐
	sms_code_str = '%06d' % random.randint(0,999999)
	current_app.logger.info(sms_code_str)

	# 2.3 保存验证码到redis
	try:
		redis_store.setex('sms_code_' + mobile, constants.SMS_CODE_REDIS_EXPIRES,sms_code_str)
	except Exception as e:
		current_app.logger.error(e)
		return jsonify(erron=RET.DBERR,errmsg='redis保存数据库错误')
	# 2.3 发送短信-->使用第三方发送
	# result = CCP().send_template_sms(mobile, [sms_code_str, 5], 1)
	# if result != '000000':
	# 	return jsonify(erron=RET.THIRDERR, errmsg='发送短信验证码失败')
	#四.返回数据
	return jsonify(errno=RET.OK, errmsg="OK")




@passport_blue.route('/image_code')
def get_image_code():
	"""
	1.获取参数
	2.生成图片验证码
	3.保存到redis中
	4.返回给浏览器
	"""

	# 1.获取参数
	image_code_id = request.args.get('image_code_id')
	if not image_code_id:
		return abort(403)

	# 2.生成图片验证码
	name, text,  image_data = captcha.generate_captcha()

	# 3.保存到redis中
	#setex:第一个Key, 时间,value
	try:

		redis_store.setex('image_code_id_' + image_code_id, constants.IMAGE_CODE_REDIS_EXPIRES, text)
	except Exception as e:
		# 3.1 日志记录错误
		logging.error(e)
		# 3.2 返回错误
		return abort(500)

	# 4.返回给浏览器
	response = make_response(image_data)
	response.headers['Content-Type']='image/jpg'
	return response
